/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.service.impl;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.comac.ins.common.core.exception.base.BaseException;
import com.comac.ins.isfd.domain.IsfdMetadataBusinessSceneDefinition;
import com.comac.ins.isfd.domain.bo.IsfdDatasourceTaskFieldMappingBo;
import com.comac.ins.isfd.domain.vo.*;
import com.comac.ins.isfd.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.comac.ins.common.core.domain.model.LoginUser;
import com.comac.ins.common.core.utils.MapstructUtils;
import com.comac.ins.common.core.utils.StringUtils;
import com.comac.ins.common.mybatis.core.page.PageQuery;
import com.comac.ins.common.mybatis.core.page.TableDataInfo;
import com.comac.ins.common.satoken.utils.LoginHelper;
import com.comac.ins.isfd.constant.enums.IsfdDatasourceTaskTargetConfigMethodEnum;
import com.comac.ins.isfd.domain.IsfdDatasourceTaskTargetConfig;
import com.comac.ins.isfd.domain.bo.IsfdDatasourceTaskTargetConfigBo;
import com.comac.ins.isfd.mapper.IsfdDatasourceDataIntegrationTaskMapper;
import com.comac.ins.isfd.mapper.IsfdDatasourceTaskTargetConfigMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 数据源数据集成任务目标配置Service业务层处理
 *
 * @author Lion Li
 * @date 2024-10-11
 */
@RequiredArgsConstructor
@Service
public class IsfdDatasourceTaskTargetConfigServiceImpl implements IIsfdDatasourceTaskTargetConfigService {

    private final IsfdDatasourceTaskTargetConfigMapper baseMapper;

    private final IIsfdDatasourceTemplateService templateService;

    private final IsfdDatasourceDataIntegrationTaskMapper isfdDatasourceDataIntegrationTaskMapper;

    private final IIsfdDatasourceTaskFieldMappingService taskFieldMappingService;

    private final IIsfdMetadataBusinessSceneDefinitionService businessSceneDefinitionService;

    private final IIsfdMetadataDatabaseService databaseService;

    /**
     * 查询数据源数据集成任务目标配置
     *
     * @param id 主键
     * @return 数据源数据集成任务目标配置
     */
    @Override
    public IsfdDatasourceTaskTargetConfigVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询数据源数据集成任务目标配置列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 数据源数据集成任务目标配置分页列表
     */
    @Override
    public TableDataInfo<IsfdDatasourceTaskTargetConfigVo> queryPageList(IsfdDatasourceTaskTargetConfigBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<IsfdDatasourceTaskTargetConfig> lqw = buildQueryWrapper(bo);
        Page<IsfdDatasourceTaskTargetConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的数据源数据集成任务目标配置列表
     *
     * @param bo 查询条件
     * @return 数据源数据集成任务目标配置列表
     */
    @Override
    public List<IsfdDatasourceTaskTargetConfigVo> queryList(IsfdDatasourceTaskTargetConfigBo bo) {
        LambdaQueryWrapper<IsfdDatasourceTaskTargetConfig> lqw = buildQueryWrapper(bo);
        List<IsfdDatasourceTaskTargetConfigVo> volist = baseMapper.selectVoList(lqw);
        for (IsfdDatasourceTaskTargetConfigVo vo : volist) {
            Long targetId = vo.getId();
            IsfdDatasourceTaskFieldMappingBo mappingBo = new IsfdDatasourceTaskFieldMappingBo();
            mappingBo.setTargetId(targetId);
            List<IsfdDatasourceTaskFieldMappingVo> mappingVos = taskFieldMappingService.queryList(mappingBo);
            if (mappingVos.isEmpty()) {
                throw new BaseException("为查询到相关字段映射信息!");
            }
            List<Map<String, String>> mapFields = mappingVos.stream().map(config -> {
                Map<String, String> map = new HashMap<>();
                map.put("targetField", config.getTargetField());
                map.put("sourceField", config.getSourceField());
                return map;
            }).toList();
            vo.setMapFields(mapFields);
        }
        return volist;
    }

    private LambdaQueryWrapper<IsfdDatasourceTaskTargetConfig> buildQueryWrapper(IsfdDatasourceTaskTargetConfigBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<IsfdDatasourceTaskTargetConfig> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getTaskId() != null, IsfdDatasourceTaskTargetConfig::getTaskId, bo.getTaskId());
        lqw.eq(bo.getConfigMethod() != null, IsfdDatasourceTaskTargetConfig::getConfigMethod, bo.getConfigMethod());
        lqw.eq(bo.getTemplateId() != null, IsfdDatasourceTaskTargetConfig::getTemplateId, bo.getTemplateId());
        lqw.like(StringUtils.isNotBlank(bo.getDataSourceName()), IsfdDatasourceTaskTargetConfig::getDataSourceName, bo.getDataSourceName());
        lqw.eq(StringUtils.isNotBlank(bo.getTargetDatabase()), IsfdDatasourceTaskTargetConfig::getTargetDatabase, bo.getTargetDatabase());
        lqw.eq(StringUtils.isNotBlank(bo.getTargetTable()), IsfdDatasourceTaskTargetConfig::getTargetTable, bo.getTargetTable());
        lqw.eq(StringUtils.isNotBlank(bo.getStrategy()), IsfdDatasourceTaskTargetConfig::getStrategy, bo.getStrategy());
        lqw.eq(bo.getIsDeleted() != null, IsfdDatasourceTaskTargetConfig::getIsDeleted, bo.getIsDeleted());
        return lqw;
    }

    /**
     * 新增数据源数据集成任务目标配置
     *
     * @param bo 数据源数据集成任务目标配置
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(IsfdDatasourceTaskTargetConfigBo bo) {
        IsfdDatasourceTaskTargetConfig add = MapstructUtils.convert(bo, IsfdDatasourceTaskTargetConfig.class);
        validEntityBeforeSave(add);
        LoginUser loginUser = LoginHelper.getLoginUser();
        bo.setCreateBy(loginUser.getUserId());
        bo.setUpdateBy(loginUser.getUserId());
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    @Override
    @Transactional
    public Boolean save(IsfdDatasourceTaskTargetConfigBo bo) {
        // 查task
        Long taskId = bo.getTaskId();
        IsfdDatasourceDataIntegrationTaskVo taskVo = isfdDatasourceDataIntegrationTaskMapper.selectVoById(taskId);
        if (taskVo == null) {
            throw new BaseException("未找到对应任务，请重试！");
        }
        // 获取配置方式
        Integer configMethod = bo.getConfigMethod();
        if (configMethod == null) {
            throw new BaseException("未选择配置方式, 请重试!");
        }

        // 如果是数据模板，查数据模板库，获取业务场景、要素库类型、模板名称
        if (IsfdDatasourceTaskTargetConfigMethodEnum.TEMPLATE.getValue().equals(configMethod)) {
            Long templateId = bo.getTemplateId();
            IsfdDatasourceTemplateVo templateVo = templateService.queryById(templateId);
            if (templateVo == null) {
                throw new BaseException("未找到相关数据模板，请重试!");
            }
        }
        // 如果是自定义配置，获取目标数据库、目标数据表、策略、数据源名称
        else if (IsfdDatasourceTaskTargetConfigMethodEnum.CUSTOMIZE.getValue().equals(configMethod)) {
            Long businessId = bo.getBusinessId();
            IsfdMetadataBusinessSceneDefinitionVo businessSceneDefinitionVo = businessSceneDefinitionService.queryById(businessId);
            if (businessSceneDefinitionVo == null) {
                throw new BaseException("未找到对应业务场景，请重试！");
            }

            Long databaseId = bo.getDatabaseId();
            IsfdMetadataDatabaseVo databaseVo = databaseService.queryById(databaseId);
            if (databaseVo == null) {
                throw new BaseException("未找到对应数据库，请重试！");
            }

            bo.setTemplateId(null);
        }

        IsfdDatasourceTaskTargetConfig targetConfig = MapstructUtils.convert(bo, IsfdDatasourceTaskTargetConfig.class);
        // 判断是修改还是新增
        Long id = bo.getId();
        bo.setIsDeleted(0);
        if (id == null) {
            baseMapper.insert(targetConfig);
            id = targetConfig.getId();
        } else {
            baseMapper.updateById(targetConfig);
        }
        // 删除旧的
        IsfdDatasourceTaskFieldMappingBo mappingBo = new IsfdDatasourceTaskFieldMappingBo();
        mappingBo.setTargetId(id);
        List<IsfdDatasourceTaskFieldMappingVo> mappingVos = taskFieldMappingService.queryList(mappingBo);
        if (!mappingVos.isEmpty()) {
            Collection<Long> mappingIds = mappingVos.stream().map(IsfdDatasourceTaskFieldMappingVo::getId).toList();
            taskFieldMappingService.deleteWithValidByIds(mappingIds, Boolean.TRUE);
        }


        // 记录字段映射关系信息
        List<Map<String, String>> mapFields = bo.getMapFields();
        for (Map<String, String> mapField : mapFields) {
            String sourceField = mapField.get("sourceField");
            String targetField = mapField.get("targetField");
            String fieldType = mapField.get("fieldType");
            String sourceTableName = mapField.get("sourceTableName");
            String targetTableName = mapField.get("targetTableName");

            IsfdDatasourceTaskFieldMappingBo fieldBo = new IsfdDatasourceTaskFieldMappingBo();
            fieldBo.setTargetId(id);
            fieldBo.setSourceField(sourceField);
            fieldBo.setTargetField(targetField);
            fieldBo.setFieldType(fieldType);
            fieldBo.setSourceTableName(sourceTableName);
            fieldBo.setTargetTableName(targetTableName);
            taskFieldMappingService.insertByBo(fieldBo);
        }

        return Boolean.TRUE;
    }

    /**
     * 修改数据源数据集成任务目标配置
     *
     * @param bo 数据源数据集成任务目标配置
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(IsfdDatasourceTaskTargetConfigBo bo) {
        IsfdDatasourceTaskTargetConfig update = MapstructUtils.convert(bo, IsfdDatasourceTaskTargetConfig.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(IsfdDatasourceTaskTargetConfig entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除数据源数据集成任务目标配置信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
